package PagePlus

import (
	"gitee.com/manoshi/go-util/exception"
	"gitee.com/manoshi/go-util/page"
	"gitee.com/manoshi/go-util/util"
	"gorm.io/gorm"
)

func QueryV2[T comparable](params []page.Param, m interface{}, data []T, orderBy string, db *gorm.DB) []T {
	tx := db.Session(&gorm.Session{PrepareStmt: true})
	dataTx := tx.Model(&m).Order(orderBy)
	if params != nil {
		for _, p := range params {
			if !util.IsEmpty(&p.Column) {
				dataTx.Where(p.Column+" "+p.Op+" ?", p.Value)
			} else if !util.IsEmpty(&p.Sql) {
				if p.Values != nil && len(p.Values) > 0 {
					dataTx.Where(p.Sql, p.Values...)
				} else if p.Value != nil {
					dataTx.Where(p.Sql, p.Value)
				} else {
					dataTx.Where(p.Sql)
				}
			}
		}
	}
	resultList := dataTx.Find(&data)
	if resultList.Error != nil {
		exception.ThrowsErr(resultList.Error)
	}
	return data
}

func PageV2[T comparable](params []page.Param, pageNum int, pageSize int, m interface{}, data []T, orderBy string, db *gorm.DB) *page.Data {
	var page = page.Data{}
	page.PageSize = util.If(pageSize == 0, 10, pageSize)
	page.PageNum = util.If(pageNum == 0, 1, pageNum)
	tx := db.Session(&gorm.Session{PrepareStmt: true})
	countTx := tx.Model(&m).Select("count(1)")
	if params != nil {
		for _, p := range params {
			if !util.IsEmpty(&p.Column) {
				countTx.Where(p.Column+" "+p.Op+" ?", p.Value)
			} else if !util.IsEmpty(&p.Sql) {
				if p.Values != nil && len(p.Values) > 0 {
					countTx.Where(p.Sql, p.Values...)
				} else if p.Value != nil {
					countTx.Where(p.Sql, p.Value)
				} else {
					countTx.Where(p.Sql)
				}
			}
		}
	}
	resultCount := countTx.Scan(&page.Total)
	if resultCount.Error != nil {
		exception.ThrowsErr(resultCount.Error)
	}
	if page.Total > 0 {
		dataTx := tx.Model(&m).Offset((page.PageNum - 1) * page.PageSize).Limit(page.PageSize).Order(orderBy)
		if params != nil {
			for _, p := range params {
				if !util.IsEmpty(&p.Column) {
					dataTx.Where(p.Column+" "+p.Op+" ?", p.Value)
				} else if !util.IsEmpty(&p.Sql) {
					if p.Values != nil && len(p.Values) > 0 {
						dataTx.Where(p.Sql, p.Values...)
					} else if p.Value != nil {
						dataTx.Where(p.Sql, p.Value)
					} else {
						dataTx.Where(p.Sql)
					}
				}
			}
		}
		resultList := dataTx.Find(&data)
		if resultList.Error != nil {
			exception.ThrowsErr(resultList.Error)
		}
		page.List = data
	}
	return &page
}

func PageNoCountV2[T comparable](params []page.Param, pageNum int, pageSize int, m interface{}, data []T, orderBy string, db *gorm.DB) *page.Data {
	var page = page.Data{}
	page.PageSize = util.If(pageSize == 0, 10, pageSize)
	page.PageNum = util.If(pageNum == 0, 1, pageNum)
	tx := db.Session(&gorm.Session{PrepareStmt: true})
	dataTx := tx.Model(&m).Offset((page.PageNum - 1) * page.PageSize).Limit(page.PageSize).Order(orderBy)
	if params != nil {
		for _, p := range params {
			if !util.IsEmpty(&p.Column) {
				dataTx.Where(p.Column+" "+p.Op+" ?", p.Value)
			} else if !util.IsEmpty(&p.Sql) {
				if p.Values != nil && len(p.Values) > 0 {
					dataTx.Where(p.Sql, p.Values...)
				} else if p.Value != nil {
					dataTx.Where(p.Sql, p.Value)
				} else {
					dataTx.Where(p.Sql)
				}
			}
		}
	}
	resultList := dataTx.Find(&data)
	if resultList.Error != nil {
		exception.ThrowsErr(resultList.Error)
	}
	page.List = data
	return &page
}
